// @ts-nocheck==
import { ref, onMounted, computed, reactive, watch } from "vue"
import { RouteRecord, useRoute } from "vue-router"
import { useRouter } from 'vue-router';
import use路由 from "@/hooks/use路由"

import { 找label } from "@/utils"
import useApi from "@/api/use增查api"
// import { 查插件api } from '@/api/插件api';
// import { ElMessage, ElMessageBox } from 'element-plus'
import * as util from "@/utils"
import * as em from "@/enums"
import { date } from 'quasar'
import * as 插组件util from 'amtf/api/插组件util';

// declare global {
//     interface Window {
//         字段集: 字段集;
//     }
// }
// 定义到default里面还不行？👇
// let 插件集: 插件集
// let 组件集: 组件集
// let 字段集: 字段集
// 组件id可以是外部指定，如果没指定，则从路由自动判断，下面有watch👇
export default function (cfg: cfg = {}) {
    const { 插件集, 组件集, 字段集 } = 插组件util
    const currentRoute = useRoute()
    const router = useRouter();
    const 路由 = use路由()

    const 指定组件id = cfg?.组件id
    const 指定字段名组 = cfg?.指定字段名组
    const a = reactive({
        插件id: "",
        字段设置集: {},
        组件id: "",
        外键关联字段集: {} as any,
        候选值集: {} as any,
        // 树标签: {
        //     value: "id",
        //     label: "名称",
        // },
        级联选择: {
            checkStrictly: true,
            expandTrigger: "hover",
            emitPath: false,
            // value: "id",
            // label: "名称",
        } as any,
    })
    if (cfg.字段设置集) Object.assign(a.字段设置集, cfg.字段设置集)
    const 插件 = reactive({})
    const 组件 = reactive({} as 组件);

    function 取组件() {
        // console.log(`取组件 ing👇`)
        let 组件id = 指定组件id
        if (!组件id) {
            // 从当前路由自动判断的
            let name = currentRoute.name
            if (!name) return
            // console.log(`路由变化 name 👉`, name)
            // 传递的可能是路由name👉 项目管理.项目信息.list
            // const sp = name.split(".")
            // if (sp.length > 2) {
            //     组件id = sp[0] + "." + sp[1]
            // }
            组件id = 插组件util.split取组件id(name as string)
        }
        a.组件id = 组件id
        if (!组件集) {
            插组件util.查插件()
        }
        util.对象重予(组件, 组件集[组件id])
        // console.log(`组件id 👉`, 组件id)
        // console.log(`组件.树结构 👉`, 组件.树结构)
        // if (组件.树结构) {
        //     console.log(`a.级联选择 👉`,a.级联选择)
        //     Object.assign(a.级联选择, 组件.树结构)
        //     a.级联选择={}
        //     console.log(`a.级联选择 👉`,a.级联选择)
        // }
    }
    取组件()

    /**树结构的label value字段设置 是在 源组件身上的，这里需要进行合并处理👇 */
    function 成级联设置(字段: 字段) {
        let res = Object.assign({}, a.级联选择, 字段.关联组件?.树结构)
        return res
    }

    function 本组件树结构() {
        let res = Object.assign({}, a.级联选择, 组件?.树结构)
        return res
    }

    function 取字段(字段名称: string) {
        const 字段id = 成字段id(字段名称)
        let 字段 = 字段集[字段id]
        return 字段
    }

    function 成字段id(字段名称: string, 组件id?: string) {
        if (!组件id) {
            组件id = a.组件id
        }
        const 字段id = 组件id + '.' + 字段名称
        return 字段id
    }

    function 成组件id(组件: 组件) {
        const 组件id = 组件.插件名 + '.' + 组件.名称
        return 组件id
    }

    function 筛选card字段(card名: string, 排除字段名组: string[]) {
        let res = 组件.字段组.filter(字段 => {
            if (!字段.cards) return false
            if (字段.是外键 == true) return false
            if (util.含其中之一(字段.名称, 排除字段名组, false)) return false
            return util.含其中之一(card名, 字段.cards, false)
        })
        return res
    }

    function 筛选详情抽屉式字段(字段名组: string[]) {
        console.log(`筛选字段 ing👇`)
        let res: 字段[] = []
        if (字段名组) {
            return 筛选指定字段(字段名组)
        }
        res = 组件.字段组.filter(字段 => {
            if (util.含其中之一(字段.名称, ['拟删除子表ids'])) {
                return false
            }
            if (字段.是外键 == true) return false
            if (字段.类型 == em.字段类型.join) return false
            return true
        })
        return res
    }

    function 筛选字段(字段名组: string[]) {
        console.log(`筛选字段 ing👇`)
        let res: 字段[] = []
        if (字段名组) {
            return 筛选指定字段(字段名组)
        }
        res = 组件.字段组.filter(字段 => {
            if (util.含其中之一(字段.名称, ['拟删除子表ids'])) {
                return false
            }
            if (字段.是外键 == true) return false
            // if (i.类型 == em.字段类型.关联字段) return false
            if (字段.关联属性?.关联类型 == em.关联类型.一对多) return false
            // console.log(`i 👉`, i)
            return true
        })
        return res
    }

    function 筛选指定字段(字段名组: string[]) {
        if (组件.状态候选值) {
            字段名组.unshift('状态')
        }
        字段名组.unshift('编号')
        let res: 字段[] = []
        res = 组件.字段组.filter(字段 => {
            return util.含其中之一(字段.名称, 字段名组, false)
        })
        util.按给定数组顺序排序(res, 字段名组)
        return res
    }

    function 筛选子表字段(字段名组: string[] = []) {
        // console.log(`筛选字段 ing👇`)
        let res: 字段[] = []
        if (字段名组.length > 0) {
            return 筛选指定字段(字段名组)
        }
        res = 组件.字段组.filter(字段 => {
            if (util.含其中之一(字段.名称, ['拟删除子表ids'])) {
                return false
            }
            if (字段.是外键 == true) return false
            // if (i.类型 == em.字段类型.关联字段) return false
            // if (字段.关联属性?.关联类型 == em.关联类型.一对多) return false
            return true
        })
        return res
    }

    const 列表显示字段s = computed(() => {
        // console.log(`筛选字段 ing👇`)
        let res: 字段[] = []
        if (指定字段名组) {
            return 筛选指定字段(指定字段名组)
        }

        res = 组件.字段组.filter(字段 => {
            if (util.含其中之一(字段.名称, ['拟删除子表ids'])) {
                return false
            }
            if (字段.名称 == '状态') {
                if (!组件.状态候选值) return false
            }
            if (字段.是外键 == true) return false
            // if (i.类型 == em.字段类型.关联字段) return false
            if (字段.关联属性?.关联类型 == em.关联类型.一对多) return false
            // console.log(`i 👉`, i)
            return true
        })
        return res
    })


    function 成标题(字段: 字段) {
        let res
        if (字段.前端设置?.动态指定列表标题) {
            return 字段.前端设置?.动态指定列表标题
        }
        if (路由.a.页面类型 == em.页面类型.详情) {
            if (字段.详情标题) return 字段.详情标题
        }
        res = 字段.标题 ? 字段.标题 : 字段.名称
        return res
    }

    let api路径 = ""
    // 如果外部指定组件id，则马上执行👇
    if (指定组件id) {
        // 取组件(指定组件id)
        let 全部路由 = router.getRoutes()
        let 路由: RouteRecord = util.查元素(全部路由, 指定组件id, 'name', true)
        api路径 = 路由.meta.api路径
    }
    const api = useApi(api路径)
    const 取候选值集 = async () => {
        try {
            const res = await api.查候选值集()
            // console.log(`查候选值集 res 👉`, res)
            if (res.code === 0) {
                // console.log(`res.data 👉`,res.data)
                a.候选值集 = res.data
                // console.log(`取候选值集 完成 ing👇`)
            }
        } catch (error) {
            console.log(`error 👉`, error)
        }
    }

    // const 取字段显示值 = (单项, 字段) => {
    //     // console.log(`单项 👉`,单项)
    //     console.log(`a.候选值集 👉`,a.候选值集)
    //     const res = 找label(a.候选值集[字段], 单项[字段])
    //     // console.log(`res 👉`,res)
    //     return res
    // }
    const 取字段显示值 = (单项: 单项, 字段: 字段) => {
        // console.log(`单项 👉`, 单项)
        // console.log(`字段 👉`, 字段)
        // console.log(`a.候选值集 👉`, a.候选值集)
        const 外键字段名 = 字段.外键字段名!
        const 候选值组 = a.候选值集[外键字段名!]

        const 外键id值 = 单项[外键字段名]
        const res = 候选值组.find(item => item.id === 外键id值)
        // console.log(`res 👉`, res)
        // const 显示值字段名 = 字段?.关联属性?.显示值字段名
        const 显示值字段名 = 字段?.关联属性?.显示值字段名;
        return res?.[显示值字段名]

    }

    const 取展开选项否 = (字段: 字段) => {
        if (字段.候选值设置?.可添加) {
            return false
        }
        if (字段.不展开选项否) {
            return false
        }
        let 候选值 = 取候选值(字段)
        if (候选值?.length! < 4) {
            return true
        }
        return false
    }

    const 取候选值 = (字段: 字段) => {
        let res
        // console.log(`字段.候选值源字段 👉`, 字段.候选值源字段)
        if (字段.候选值源字段) {
            // console.log(`字段.候选值源字段 👉`,字段.候选值源字段)
            if (字段.候选值源字段.includes('.设置')) {
                res = a.候选值集[字段.名称]
            } else {
                let 对应字段名 = 插组件util.split取最末字符(字段.候选值源字段)
                res = a.候选值集[字段.名称]?.map((item: any) => {
                    return { label: item[对应字段名], value: item[对应字段名] }
                })
            }
        }
        // 直接在本 字段 定义 的情况
        else {
            res = 字段.候选值?.map((item) => {
                return { label: item, value: item }
            })
        }
        return res
    }

    const 外键组 = computed(() => {
        const res = []
        res.push({ 字段名: "创建者", })
        res.push({ 字段名: "更新者", })
        let arr = []
        组件.字段组.map((字段) => {
            if (字段.是外键) {
                res.push({
                    字段名: 字段.名称,
                })
            }
        })
        return res
    })
    // for (const 外键 of 外键组.value) {
    //     // 予初始值,防止vue模板报错
    //     外键关联字段集[外键.字段名] = {}
    // }
    async function 查外键关联字段集(单项) {
        for (const 外键 of 外键组.value) {
            // 前面的 字段名 是简称，go中实际字段名加了 id
            // let 实际字段名 = 外键.字段名
            // if (!util.含其中之一(外键.字段名, ['创建者', '更新者'])) {
            //     实际字段名 = 外键.字段名 + 'id'
            // }
            // console.log(`外键 👉`, 外键)
            let id = 单项[外键.字段名]
            外键.id = `${id}`
        }
        const res = await api.查外键关联字段集({ 外键组: JSON.stringify(外键组.value) })
        // console.log(`查外键关联字段集res 👉`, res)
        if (res.code === 0) {
            a.外键关联字段集 = res.data
        }
    }

    function 流程结束否(单项) {
        const index = 组件.状态候选值.indexOf(单项.状态);
        // console.log(`index 👉`,index)
        let res = index == 组件.状态候选值.length - 1
        return res
    }

    function 是流程初始状态(单项) {
        const index = 组件.状态候选值.indexOf(单项.状态);
        // console.log(`index 👉`,index)
        let res = index == 0
        return res
    }

    // watch(
    //     () => currentRoute,
    //     (newValue, oldValue) => {
    //         if (指定组件id) return
    //         if (!currentRoute) {
    //             return "非url情况？"
    //         }
    //         let name = currentRoute.name
    //         if (!name) return
    //         // console.log(`路由变化 name 👉`, name)
    //         取组件(name)
    //     },
    //     { immediate: true }
    // )

    function 取组件单项模板(组件id?) {
        if (!组件id) 组件id = a.组件id
        let 组件单项模板 = util.深拷贝(组件集[组件id].model)
        // let 组件单项模板 = util.深拷贝(组件集[组件id].组件单项模板)
        console.log(`util.取组件单项模板 模板 👉`, 组件单项模板)
        util.删除部分对象属性(组件单项模板, ["DeletedAt", "CreatedAt"])
        const timeStamp = Date.now()
        const formattedString = date.formatDate(timeStamp, 'YYYY-MM-DDTHH:mm:ss.SSSZ')
        组件单项模板.UpdatedAt = formattedString
        组件单项模板.id = Date.now() * -1
        // util.删除部分对象属性(组件单项模板, ["id", "UpdatedAt", "DeletedAt", "CreatedAt"])
        // console.log(`util.取组件单项模板 模板 👉`, 模板)
        return 组件单项模板
    };

    // 如果传递了 字段名称，就跳转该字段对应的关联组件详情页
    function 跳转单独详情页(单项, 字段名称) {
        let 组件id
        // 没传递 字段名称 跳转 本组件详情页
        if (!字段名称) {
            组件id = a.组件id
        }
        // 如果传递了 就跳转该字段 对应的关联组件 详情页
        else {
            // 跳转字段的关联组件详情
            let 字段id = 成字段id(字段名称)
            const 字段 = 字段集[字段id]
            const 关联组件 = 字段.关联组件!
            组件id = 成组件id(关联组件)
        }
        router.push({ name: 组件id + '.详情', query: { id: 单项.id, 编号: 单项.编号 } })
        return true
    }

    // watch(() => a.级联选择, (newValue, oldValue) => {
    //     console.log(`newValue 👉`, newValue)
    // }, { deep: true })

    return {
        是流程初始状态,
        本组件树结构,
        筛选子表字段,
        筛选详情抽屉式字段,
        流程结束否,
        列表显示字段s,
        成级联设置,
        取组件,
        查外键关联字段集,
        成组件id,
        取展开选项否,
        取候选值,
        取字段,
        筛选card字段,
        成标题,
        筛选字段,
        跳转单独详情页,
        成字段id,
        取组件单项模板,
        取候选值集,
        取字段显示值,
        a,
        api路径,
        插件,
        组件,
    } as 插组件
}
